/**
 * 判断对象是不是一个错误对象，包含errorType属性则为错误对象
 *
 * @method isErrorObject
 * @param {Object} param 参数数组
 * @return {Boolean} 是否为错误对象
 */
function isErrorObject(object) {
    return typeof object.errorType === 'string'
}
/**
 * 获取随机数
 * @method getRandomInt
 * @param n
 * @return {Number}
 */
function getRandomInt(n) {
    return Math.round(Math.random() * n)
}
/**
 * 跳转页面
 * @method goRouter
 * @param router
 */
function goRouter(router) {
    window.location.hash = router
}
/**
 * unicode编码
 * @method encodeMessage
 * @param textString {String}
 * @return {String} 
 */
function encodeMessage(textString) {
    var haut = 0;
    var result = '';
    if (!textString) return result;
    for (var i = 0; i < textString.length; i++) {
        var b = textString.charCodeAt(i);
        if (haut != 0) {
            if (0xDC00 <= b && b <= 0xDFFF) {
                result += dec2hex(0x10000 + ((haut - 0xD800) << 10) + (b - 0xDC00));
                haut = 0;
                continue;
            } else {
                haut = 0;
            }
        }
        if (0xD800 <= b && b <= 0xDBFF) {
            haut = b;
        } else {
            cp = dec2hex(b);
            while (cp.length < 4) {
                cp = '0' + cp;
            }
            result += cp;
        }
    }
    return result;
}

/**
 * 尝试disable掉checkbox，如果len > 0就enable
 * @method tryToDisableCheckAll
 * @param checkbox
 * @param len
 */
function tryToDisableCheckAll(checkbox, len) {
    if (len == 0) {
        disableCheckbox(checkbox);
    } else {
        enableCheckbox(checkbox);
    }
}

/**
 * GSM7编码表
 * @attribute {Array} GSM7_Table
 */
var GSM7_Table = ["000A", "000C", "000D", "0020", "0021", "0022", "0023", "0024", "0025", "0026", "0027", "0028",
    "0029", "002A", "002B", "002C", "002D", "002E", "002F", "0030", "0031", "0032", "0033", "0034", "0035", "0036",
    "0037", "0038", "0039", "003A", "003A", "003B", "003C", "003D", "003E", "003F", "0040", "0041", "0042", "0043",
    "0044", "0045", "0046", "0047", "0048", "0049", "004A", "004B", "004C", "004D", "004E", "004F", "0050", "0051",
    "0052", "0053", "0054", "0055", "0056", "0057", "0058", "0059", "005A", "005B", "005C", "005D", "005E", "005F",
    "0061", "0062", "0063", "0064", "0065", "0066", "0067", "0068", "0069", "006A", "006B", "006C", "006D", "006E",
    "006F", "0070", "0071", "0072", "0073", "0074", "0075", "0076", "0077", "0078", "0079", "007A", "007B", "007C",
    "007D", "007E", "00A0", "00A1", "00A3", "00A4", "00A5", "00A7", "00BF", "00C4", "00C5", "00C6", "00C7", "00C9",
    "00D1", "00D6", "00D8", "00DC", "00DF", "00E0", "00E4", "00E5", "00E6", "00E8", "00E9", "00EC", "00F1", "00F2",
    "00F6", "00F8", "00F9", "00FC", "0393", "0394", "0398", "039B", "039E", "03A0", "03A3", "03A6", "03A8", "03A9",
    "20AC"
];
/**
 * GSM7扩展编码表
 * @attribute {Array} GSM7_Table_Extend
 */
var GSM7_Table_Extend = ["007B", "007D", "005B", "005D", "007E", "005C", "005E", "20AC", "007C"];
/**
 * 获取编码类型
 * @method getEncodeType
 * @param {String} strMessage 待编码字符串
 * @return {String}
 */
function getEncodeType(strMessage) {
    var encodeType = "GSM7_default";
    var gsm7_extend_char_len = 0;
    if (!strMessage) {
        return { encodeType: encodeType, extendLen: gsm7_extend_char_len };
    }
    for (var i = 0; i < strMessage.length; i++) {
        var charCode = strMessage.charCodeAt(i).toString(16).toUpperCase();
        while (charCode.length != 4) {
            charCode = "0" + charCode;
        }
        if ($.inArray(charCode, GSM7_Table_Extend) != -1) {
            gsm7_extend_char_len++;
        }
        if ($.inArray(charCode, GSM7_Table) == -1) {
            encodeType = "UNICODE";
            gsm7_extend_char_len = 0;
            break;
        }
    }
    return { encodeType: encodeType, extendLen: gsm7_extend_char_len };
}

function getSmsCount(str) {
    var encodeType = getEncodeType(str);
    var len = str.length,
        gsm7 = encodeType.encodeType != "UNICODE",
        needChunking = false,
        chunkSize = 0;
    if (gsm7) {
        needChunking = (len + encodeType.extendLen) > 160;
        chunkSize = 153;
    } else {
        needChunking = len > 70;
        chunkSize = 67;
    }
    if (needChunking) {
        return Math.ceil((len + encodeType.extendLen) / chunkSize);
    } else {
        return 1;
    }
}

function getInsertPos(textbox) {
    var iPos = 0;
    if (textbox.selectionStart || textbox.selectionStart == "0") {
        iPos = textbox.selectionStart;
    } else if (document.selection) {
        textbox.focus();
        var range = document.selection.createRange();
        var rangeCopy = range.duplicate();
        rangeCopy.moveToElementText(textbox);
        while (range.compareEndPoints("StartToStart", rangeCopy) > 0) {
            range.moveStart("character", -1);
            iPos++;
        }
    }
    return iPos;
}

function setInsertPos(textbox, iPos) {
    textbox.focus();
    if (textbox.selectionStart || textbox.selectionStart == "0") {
        textbox.selectionStart = iPos;
        textbox.selectionEnd = iPos;
    } else if (document.selection) {
        var range = textbox.createTextRange();
        range.moveStart("character", iPos);
        range.collapse(true);
        range.select();
    }
}

var specialChars = ['000D', '000A', '0009', '0000']
var specialCharsIgnoreWrap = ['0009', '0000']
    /**
     * unicode解码
     * @method decodeMessage
     * @param str
     * @param ignoreWrap {Boolean} 忽略回车换行
     * @return any
     */
function decodeMessage(str, ignoreWrap) {
    if (!str) return ''
    var specials = specialCharsIgnoreWrap //ignoreWrap ? specialCharsIgnoreWrap : specialChars;
    return str.replace(/([A-Fa-f0-9]{1,4})/g, function(matchstr, parens) {
        if ($.inArray(parens, specials) == -1) {
            return hex2char(parens)
        } else {
            return ''
        }
    })
}

function dec2hex(textString) {
    return (textString + 0).toString(16).toUpperCase()
}

function hex2char(hex) {
    var result = ''
    var n = parseInt(hex, 16)
    if (n <= 0xffff) {
        result += String.fromCharCode(n)
    } else if (n <= 0x10ffff) {
        n -= 0x10000
        result +=
            String.fromCharCode(0xd800 | (n >> 10)) +
            String.fromCharCode(0xdc00 | (n & 0x3ff))
    }
    return result
}
/**
 * 去除编码中的回车换行等特殊字符
 * @method escapeMessage
 * @param msg
 * @return any 
 */
function escapeMessage(msg) {
    return msg;
}

/**
 * 将电话号码中的+号转换成_.jquery选择器中不能有+号
 * @method convertNumberToId
 * @param number {String} 电话号码
 * @return {String}
 */
function convertNumberToId(number) {
    return number.replace(/[\+\*#]/g, '_');
}

/**
 * 获取号码末8/11位
 * @method getLastNumber
 * @param number {String} 电话号码
 * @param len {String} 获取位数8或11
 * @return
 */
function getLastNumber(number, len) {
    if (number.length > len) {
        return convertNumberToId(number.substring(number.length - len, number.length));
    }
    return convertNumberToId(number);
}

/**
 * 调整ie8以下的table高度
 * @method fixTableHeight
 */
function fixTableHeight() {
    if ($.browser.msie) {
        var heightTimer = setInterval(function() {
            var $table = $(".fixTableScroll")[0];
            if ($table) {
                var scrollHeight = $table.scrollHeight;
                if (scrollHeight != 0) {
                    $table.style.height = scrollHeight + 20;
                    window.clearInterval(heightTimer);
                }
            } else {
                //快速切换菜单需要清除定时器
                window.clearInterval(heightTimer);
            }
        }, 300);
    }
}

function refreshTableHeight() {
    if ($.browser.msie) {
        $(".fixTableScroll")[0].style.height = $(".fixTableScroll .ko-grid-container")[0].scrollHeight + 35;
    }
}

function transTime(data) {
    var dateArr = data.split(",");
    if (dateArr.length == 0 || ("," + data + ",").indexOf(",,") != -1) {
        return "";
    } else {
        var time = dateArr[0] + "/" + dateArr[1] + "/" + dateArr[2] + " " + leftInsert(dateArr[3], 2, '0') + ":" + leftInsert(dateArr[4], 2, '0') + ":" +
            leftInsert(dateArr[5], 2, '0');
        return time;
    }
}

/**
 * 长度不足时，左侧插入特定字符
 * @param {String} value
 * @param {Integer} length
 * @param {String} placeholder
 * @return {String}
 */
function leftInsert(value, length, placeholder) {
    var len = value.toString().length;
    for (; len < length; len++) {
        value = placeholder + value;
    }
    return value;
}

var _timeoutStack = []
var _intervalStack = []

function addTimeout(code, delay) {
    var time = window.setTimeout(code, delay)
    _timeoutStack.push(time)
    return time
}

function addInterval(code, delay) {
    var time = window.setInterval(code, delay)
    _intervalStack.push(time)
    return time
}

function clearTimer() {
    clearTimeoutTimer()
    clearIntervalTimer()
}

function clearTimeoutTimer() {
    for (var i = 0; i < _timeoutStack.length; i++) {
        window.clearTimeout(_timeoutStack[i])
    }
    _timeoutStack = []
}

function clearIntervalTimer() {
    for (var i = 0; i < _intervalStack.length; i++) {
        window.clearInterval(_intervalStack[i])
    }
    _intervalStack = []
}

/**
 * 获取当前时间.格式如：2012；01；02；12；33；44+800
 * @method getCurrentTimeString
 * @param {Date} theTime
 * @return {String}
 */
function getCurrentTimeString(theTime) {
    var time = "";
    var d = theTime ? theTime : new Date();
    time += (d.getFullYear() + "").substring(2) + ";";
    time += getTwoDigit((d.getMonth() + 1)) + ";" + getTwoDigit(d.getDate()) + ";" + getTwoDigit(d.getHours()) + ";" +
        getTwoDigit(d.getMinutes()) + ";" + getTwoDigit(d.getSeconds()) + ";";

    if (d.getTimezoneOffset() < 0) {
        time += "+" + (0 - d.getTimezoneOffset() / 60);
    } else {
        time += (0 - d.getTimezoneOffset() / 60);
    }
    return time;
}
/**
 * 字符串长度不足两位，前面补零
 * @method getTwoDigit
 * @return {String}
 */
function getTwoDigit(num) {
    num += "";
    while (num.length < 2) {
        num = "0" + num;
    }
    return num;
}

function getDisplayVolume2(volume, isSpeed) {
    volume = parseInt(volume, 10);
    if (volume == 0 || isNaN(volume)) {
        return "0" + $.i18n.prop('B');;
    } else if (volume == "") {
        return "";
    }
    var needReverse = false;
    if (volume < 0) {
        needReverse = true;
        volume = 0 - volume;
    }
    var numberOfBytesInOneB = 1;
    var numberOfBytesInOneKB = numberOfBytesInOneB * 1024;
    var numberOfBytesInOneMB = numberOfBytesInOneKB * 1024;
    var numberOfBytesInOneGB = numberOfBytesInOneMB * 1024;
    var numberOfBytesInOneTB = numberOfBytesInOneGB * 1024;

    var labelForOneB = $.i18n.prop('B');
    var labelForOneKB = $.i18n.prop('KB');
    var labelForOneMB = $.i18n.prop('MB');
    var labelForOneGB = $.i18n.prop('GB');
    var labelForOneTB = $.i18n.prop('TB');
    if (isSpeed) {
        volume = volume * 8;
    }
    var vol = volume / numberOfBytesInOneTB;
    var displayString = roundToTwoDecimalNumber(vol) + labelForOneTB;
    if (vol < 0.5) {
        vol = volume / numberOfBytesInOneGB;
        displayString = roundToTwoDecimalNumber(vol) + labelForOneGB;

        if (vol < 0.5) {
            vol = volume / numberOfBytesInOneMB;
            displayString = roundToTwoDecimalNumber(vol) + labelForOneMB;

            if (vol < 0.5) {
                vol = volume / numberOfBytesInOneKB;
                displayString = roundToTwoDecimalNumber(vol) + labelForOneKB;

                if (vol < 0.5) {
                    vol = volume;
                    displayString = roundToTwoDecimalNumber(vol) + labelForOneB;
                }
            }
        }
    }
    if (needReverse) {
        displayString = "-" + displayString;
    }
    return displayString;
}

/**
 * 将数字保留两位小数
 * @method roundToTwoDecimalNumber
 * @param {Integer} num 浮点数值
 */
function roundToTwoDecimalNumber(num) {
    return Math.round(num * 100) / 100;
}

/**
 * HTML编码转换
 * @method HTMLEncode
 * @param {String} html 待编码内容
 */
function HTMLEncode(html) {

    return Escape.html(html);
}

/**
 * HTML解码转换
 * @method HTMLDecode
 * @param {String} text 待解码内容
 */
function HTMLDecode(text) {
    var temp = document.createElement("div");
    temp.innerHTML = text;
    var output = temp.innerText || temp.textContent;
    output = output.replace(new RegExp("&nbsp;", "gm"), " ");
    temp = null;
    return output;
}

var Escape = {
    html: function(string) {
        return (string + '').replace(/[&<>"'\/`]/g, Escape._htmlReplacer);
    },
    regex: function(string) {
        return (string + '').replace(/[\-$\^*()+\[\]{}|\\,.?\s]/g, '\\$&');
    },
    _htmlReplacer: function(match) {
        return Escape.HTML_CHARS[match];
    },
    HTML_CHARS: {
        '&': '&amp;',
        '<': '&lt;',
        '>': '&gt;',
        '"': '&quot;',
        "'": '&#x27;',
        '/': '&#x2F;',
        '`': '&#x60;'
    }
};

/**
 * URL编码转换
 * @method URLEncode
 * @param {String} url 待编码内容
 */
function URLEncodeComponent(url) {
    return encodeURIComponent(url);
}

function URLEncode(url) {
    return encodeURI(url);
}

// 排序
function phSortAlgo(charA, charB) {
    var charlist =
        '.,?!\'"()@\\/:_;+-*=%&<>£$¥§€¤[]{}~# 1234567890АаБбВвГгДдЕеЁёЖжЗзИиЙйКкЛлМмНнОоПпРрСсТтУуФфХхЦцЧчШшЩщЪъЫыЬьЭэЮюЯяAaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz',
        codeA = -1,
        codeB = -1

    if (charlist.indexOf(charA) > -1) codeA = charlist.indexOf(charA)
    else codeA = charA.charCodeAt() + 163

    if (charlist.indexOf(charB) > -1) codeB = charlist.indexOf(charB)
    else codeB = charB.charCodeAt() + 163
    return codeA - codeB
}

/**
 * 转化协议
 * //from 4.0
 * @method transProtocol
 * @return {*}
 */
function transProtocol(proto) {
    var type = "ALL";
    if ("1" == proto)
        type = "TCP";
    else if ("2" == proto)
        type = "UDP";
    else if ("3" == proto)
        type = "TCP+UDP";
    else if ("4" == proto)
        type = "ICMP";
    else if ("5" == proto)
        type = "ALL";
    return type;
}

function transProtocolValue(proto) {
    switch (proto) {
        case "TCP":
        case "UDP":
        case "ICMP":
            return proto;
        case "TCP&UDP":
            return "TCP+UDP";
        case "None":
        default:
            return "ALL";
    }
}

/**
 * 检查数值范围
 * @method checkRange
 */
function checkRange(str, min, max) {
    var intVal = parseInt(str, 10);
    return !(intVal > max || intVal < min);
}

/**
 * 检查checkbox状态，重绘checkbox
 * @method renderCheckbox
 */
function renderCheckbox() {
    var checkboxToggle = $(".checkboxToggle");

    checkboxToggle.each(function() {
        checkBoxesSize($(this));
    });

    var checkboxes = $(".checkbox").not("[class*='checkboxToggle']").find("input:checkbox");
    if (checkboxes.length == 0) {
        disableCheckbox(checkboxToggle);
    } else {
        enableCheckbox(checkboxToggle);
    }
    checkboxes.each(function() {
        checkCheckbox($(this));
    });
}

function checkBoxesSize(selectAll) {
    var target = selectAll.attr("target");
    var boxSize = $("#" + target + " .checkbox input:checkbox").length;
    var checkedBoxSize = $("#" + target + " .checkbox input:checkbox:checked").length;
    var checkbox = selectAll.find("input:checkbox");
    if (boxSize != 0 && boxSize == checkedBoxSize) {
        checkbox.attr("checked", "checked");
    } else {
        checkbox.removeAttr("checked");
    }
    checkP(checkbox);
}

function checkSelectAll(selectAll, target) {
    var theCheckbox = $("#" + target + " .checkbox input:checkbox");
    if (selectAll.attr("checked")) {
        theCheckbox.attr("checked", "checked");
    } else {
        theCheckbox.removeAttr("checked");
    }
    theCheckbox.each(function() {
        checkCheckbox($(this));
    });
}

function checkCheckbox(checkbox) {
    if (checkbox.closest("p.checkbox").hasClass("checkboxToggle")) {
        checkSelectAll(checkbox, checkbox.closest("p.checkbox").attr("target"));
    }
    checkP(checkbox);
    checkBoxesSize($("#" + checkbox.attr("target")));
}

function checkP(checkbox) {
    if (checkbox.attr("checked")) {
        checkbox.closest("p.checkbox").addClass("checkbox_selected");
    } else {
        checkbox.closest("p.checkbox").removeClass("checkbox_selected");
    }
}

function mac_check(macaddr) {
    macaddr = macaddr.toUpperCase();
    if (macaddr.length != 12 && macaddr.length != 17) return false;
    if (macaddr == "00-00-00-00-00-00" || macaddr == "00:00:00:00:00:00" || macaddr == "FF-FF-FF-FF-FF-FF" || macaddr == "FF:FF:FF:FF:FF:FF") return false;
    var reg = /^[A-Fa-f0-9]{12}$/
    var reg1 = /^[A-Fa-f0-9]{1,2}\-[A-Fa-f0-9]{1,2}\-[A-Fa-f0-9]{1,2}\-[A-Fa-f0-9]{1,2}\-[A-Fa-f0-9]{1,2}\-[A-Fa-f0-9]{1,2}$/;
    var reg2 = /^[A-Fa-f0-9]{1,2}\:[A-Fa-f0-9]{1,2}\:[A-Fa-f0-9]{1,2}\:[A-Fa-f0-9]{1,2}\:[A-Fa-f0-9]{1,2}\:[A-Fa-f0-9]{1,2}$/;
    if (reg.test(macaddr)) {
        return true;
    } else if (reg1.test(macaddr)) {
        return true;
    } else if (reg2.test(macaddr)) {
        return true;
    } else {
        return false;
    }
}

function isNull(str) {
    if (str == "") return true;
    else return false;
}

function isIP(strIP) {
    var patrn = /^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/;
    if (isNull(strIP)) return false;
    if (!patrn.exec(strIP)) {
        return false;
    }

    laststr = strIP.split(".");
    if (parseInt(laststr[0]) > 255 || parseInt(laststr[1]) > 255 || parseInt(laststr[2]) > 255 || parseInt(laststr[3]) > 255) {
        return false;
    }
    return true;
}

function isIPV6(ipvalue) {
    var matchStr = /^\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(%.+)?\s*$/

    var ret = ipvalue.match(matchStr)
    if (ret) {
        return true
    } else {
        return false
    }
}

function esc(str) {
    str = '' + str;
    str = str.replace(/%/g, '%25');
    str = str.replace(/&/g, '%26');
    str = str.replace(/=/g, '%3D');
    str = str.replace(/\+/g, '%2B');
    str = str.replace(/ /g, '+');
    str = str.replace(/\\/g, '%5C');
    return str;
}

/**
 * 显示等待遮罩
 * @method showLoading
 * @param {String} msg
 * @param {String} content loading 文本
 */
function showLoading(msg) {
    if (msg) {
        msg = $.i18n.prop(msg);
        $('#loadMsg').html(msg)
    }
    $('#loading').modal({
        position: '30%',
        overlayId: 'confirm-overlay',
        containerId: 'confirm-container',
        minHeight: 160,
        persist: true,
        focus: false,
        escClose: true,
        opacity: 80
    })
}
/**
 * 隐藏等待遮罩
 * @method hideLoading
 */
function hideLoading() {
    $.modal.close()
    $('#loadMsg').html('')
    $('#load-content').html('')
}

/**
 * 显示确认框
 * @method showLoading
 * @param {String} title
 * @param {String} content loading 文本
 */
function showConfirm(title, content, yescallback, nocallback, minHeightVal) {
    if (title) {
        title = $.i18n.prop(title);
        $('#confirm-title').html(title)
    } else {
        $('#confirm-title').html($.i18n.prop("Confirmation"))
    }
    $('#confirm').modal({
        position: '30%',
        overlayId: 'confirm-overlay',
        containerId: 'confirm-container',
        minHeight: minHeightVal ? minHeightVal : 160,
        persist: true,
        focus: false,
        escClose: false,
        opacity: 80
    })
    if (content) {
        if (typeof content == 'string') {
            content = $.i18n.prop(content);
            $('#confirm-content').html(content)
        } else {
            var params = [content.msg];
            params.push(content.params);
            $('#confirm-content').html($.i18n.prop.apply(null, _.flatten(params)));
        }
    }
    $('#yesbtn').html($.i18n.prop("yes"))
    $('#nobtn').html($.i18n.prop("no"))
    $('#yesbtn').unbind('click').click(function(e) {
        e && e.preventDefault()
        hideConfirm();
        if ($.isFunction(yescallback)) {
            yescallback();
        }
    });

    $('#nobtn,#closeBtn').unbind('click').click(function(e) {
        e && e.preventDefault()
        hideConfirm();
        if ($.isFunction(nocallback)) {
            nocallback();
        }
    });
}

// /**
//  * 弹出confirm提示框
//  * @method showConfirm
//  * @param {Object|String} msgObj
//  * @param {Function} callback confirm确认后的回调函数
//  * 		如果需要绑定Yes,No两个回调事件，传对象{ok: function(){}, no: function(){}}
//  * @param {Number} minHeight
//  */
// function showConfirm(msgObj, callback, minHeight, yesTrans, noTrans) {
//     if (yesTrans) {
//         $('#yesbtn').attr("data-trans", yesTrans);
//     } else {
//         $('#yesbtn').attr("data-trans", "yes");
//     }
//     if (noTrans) {
//         $('#nobtn').attr("data-trans", noTrans);
//     } else {
//         $('#nobtn').attr("data-trans", "no");
//     }
//     $('#yesbtn, #nobtn').translate();
//     var option = {
//         title: 'confirm',
//         img: 'img/confirm.png',
//         msg: msgObj,
//         minHeight: minHeight
//     };

//     popup(option);

//     $('#yesbtn, #nobtn').show();
//     $('#okbtn').hide();

//     var callbackIsFunction = $.isFunction(callback);
//     var callbackIsPojo = $.isPlainObject(callback);
//     $('#yesbtn').unbind('click').click(function() {
//         $.modal.close();
//         if (callbackIsFunction) {
//             callback();
//         } else if (callbackIsPojo && $.isFunction(callback.ok)) {
//             callback.ok();
//         }
//     });

//     $('#nobtn').unbind('click').click(function() {
//         $.modal.close();
//         if (callbackIsPojo && $.isFunction(callback.no)) {
//             callback.no();
//         }
//     });
// }

/**
 * 自定义弹出框
 * @method popup
 * @param option
 */
function popup(option) {
    $.modal.close();
    var minHeight = option.minHeight || 140;
    $('#confirm').modal({
        zIndex: 3000,
        position: ["30%"],
        overlayId: 'confirm-overlay',
        containerId: 'confirm-container',
        escClose: false,
        minHeight: minHeight
    });
    var $confirmDiv = $('div#confirm');
    $('#confirmImg', $confirmDiv).attr('src', option.img);
    $('#popTitle', $confirmDiv).html($.i18n.prop(option.title));
    if (typeof option.msg == 'string') {
        $('.message', $confirmDiv).html($.i18n.prop(option.msg));
    } else {
        var params = [option.msg.msg];
        params.push(option.msg.params);
        $('.message', $confirmDiv).html($.i18n.prop.apply(null, _.flatten(params)));
    }
    var $promptDiv = $("div.promptDiv", $confirmDiv);
    if (option.showInput === true) {
        $promptDiv.show();
        $("input#promptInput", $promptDiv).val(option.defaultValue ? option.defaultValue : "");
        $(".promptErrorLabel", $promptDiv).empty();
    } else {
        $promptDiv.hide();
    }

    window.setTimeout(function() {
        $(':input:enabled:visible:first', '#confirm-container').focus();
    }, 0);
}

/**
 * 显示确认框
 * @method showLoading
 * @param {String} msg
 * @param {String} content loading 文本
 */
function showAlert(content, callback, param) {
    hideLoading()
    content = $.i18n.prop(content);
    if (param) {
        for (var i = 0; i < param.length; i++) {
            content = content.replace('{' + i + '}', param[i])
        }
    }
    $('#confirm-title').html($.i18n.prop("Warning"))
    $('#confirm').modal({
        position: '30%',
        overlayId: 'confirm-overlay',
        containerId: 'confirm-container',
        minHeight: 160,
        persist: true,
        focus: false,
        escClose: false,
        opacity: 80
    })
    if (content) {
        $('#confirm-content').html(content)
    }
    $('#yesbtn').html($.i18n.prop("ok"))
    $('#yesbtn').unbind('click').click(function(e) {
        e && e.preventDefault()
        hideConfirm();
        if ($.isFunction(callback)) {
            callback();
        }
    });
    $('#nobtn').hide()
    $('#nobtn,#closeBtn').unbind('click').click(function(e) {
        e && e.preventDefault()
        hideConfirm();
    });
}

/**
 * 显示确认框
 * @method showLoading
 * @param {String} msg
 * @param {String} content loading 文本
 */
function showTip(title, content, callback) {
    hideLoading()
    content = $.i18n.prop(content);
    $('#confirm-title').html($.i18n.prop(title))
    $('#confirm').modal({
        position: '30%',
        overlayId: 'confirm-overlay',
        containerId: 'confirm-container',
        minHeight: 160,
        persist: true,
        focus: false,
        escClose: false,
        opacity: 80
    })
    $('#confirm-content').html(content)
    $('#yesbtn').html($.i18n.prop("ok"))
    $('#yesbtn').unbind('click').click(function(e) {
        e && e.preventDefault()
        hideConfirm();
        if ($.isFunction(callback)) {
            callback();
        }
    });
    $('#nobtn').hide()
    $('#nobtn,#closeBtn').unbind('click').click(function(e) {
        e && e.preventDefault()
        hideConfirm();
    });
}

/**
 * 显示确认框
 * @method showLoading
 * @param {String} msg
 * @param {String} content loading 文本
 */
function showInfo(content, callback, param, minHeightVal) {
    content = $.i18n.prop(content);
    if (param) {
        for (var i = 0; i < param.length; i++) {
            content = content.replace('{' + i + '}', param[i])
        }
    }
    $('#confirm-title').html($.i18n.prop("info"))
    $('#confirm').modal({
        position: '30%',
        overlayId: 'confirm-overlay',
        containerId: 'confirm-container',
        minHeight: minHeightVal ? minHeightVal : 160,
        persist: true,
        focus: false,
        escClose: false,
        opacity: 80
    })
    if (content) {
        $('#confirm-content').html(content)
    }
    $('#yesbtn').html($.i18n.prop("ok"))
    $('#yesbtn').unbind('click').click(function(e) {
        e && e.preventDefault()
        hideConfirm();
        if ($.isFunction(callback)) {
            callback();
        }
    });
    $('#nobtn').hide()
    $('#nobtn,#closeBtn').unbind('click').click(function(e) {
        e && e.preventDefault()
        hideConfirm();
    });
}

/**
 * 显示确认框
 * @method showLoading
 * @param {String} msg
 * @param {String} content loading 文本
 */
function showInfo2(content) {
    content = $.i18n.prop(content);
    $('#confirm-title').html($.i18n.prop("info"))
    $('#confirm').modal({
        position: '30%',
        overlayId: 'confirm-overlay',
        containerId: 'confirm-container',
        minHeight: 160,
        persist: true,
        focus: false,
        escClose: false,
        opacity: 80
    })
    if (content) {
        $('#confirm-content').html(content)
    }
    $('#yesbtn,#closeBtn,#nobtn').hide();
}

/**
 * 隐藏确认框
 * @method hideLoading
 */
function hideConfirm() {
    $.modal.close()
    $('#confirm-title').html('')
    $('#confirm-content').html('')

    $('#yesbtn').html($.i18n.prop("yes"))
    $('#nobtn').html($.i18n.prop("no"))

    $('#yesbtn').show()
    $('#nobtn').show()
}

function convertSignalStr(data) {
    var type_2g = ["GSM", "GPRS", "EDGE", "G", "E"];
    var type_3g = ["UJAZZ", "HSDPA", "HSUPA", "HSPA", "HSPA+", "DC", "DC-HSPA", "DC-HSPA+", "WCDMA", "TD-SCDMA", "TD", "3G"];
    var type_4g = ["LTE", "4G", "FDD", "TDD"];
    if ($.inArray(data.network_type, type_2g) != -1) {
        return "2G"
    } else if ($.inArray(data.network_type, type_3g) != -1) {
        return "3G"
    } else if ($.inArray(data.network_type, type_4g) != -1) {
        if (data.network_type == '4G') {
            return '4G';
        }

        if (data.network_type == 'LTE') {
            return data.sub_network_type;
        }

        return "4G-" + data.network_type;
    } else if (data.network_type.toLowerCase() == 'limited service') {
        return $.i18n.prop('limitedService');
    }

    return data.network_type;
}

/**
 * 翻译联网时长
 * 
 * @method transSecond2Time
 * @param {Number}
 *            secs 联网时间（秒）
 */
function transSecond2Time(secs) {
    secs = parseInt(secs, 10);
    if (isNaN(secs)) {
        secs = 0;
    }
    var isNegative = false;
    if (secs < 0) {
        isNegative = true;
        secs = 0 - secs;
    }
    var hour = Math.floor(secs / 3600);
    secs = secs % 3600;
    var minu = Math.floor(secs / 60);
    secs = secs % 60;
    if ($.i18n.prop('language') == 'ru') {
        return (isNegative ? '-' : '') + hour + " д " + minu + " ч " + secs + " мин ";
    } else {
        return (isNegative ? '-' : '') + leftInsert(hour, 2, '0') + ":" + leftInsert(minu, 2, '0') + ":" + leftInsert(secs, 2, '0');
    }
}

function checkcharwidth(str) {
    var cArr = str.match(/[^\x00-\xff]/ig);
    return (cArr == null ? false : true);
}

function getSwitch(id) {
    var o = $("#" + id);
    if (o.attr("class") == "bg-switch-enable") {
        return true;
    } else {
        return false;
    }
}

function setSwitch(id, val) {
    var o = $("#" + id);
    if (val) {
        o.attr("class", "bg-switch-enable");
        o.next(".switch_note").html($.i18n.prop("enable"));
    } else {
        o.attr("class", "bg-switch-disable");
        o.next(".switch_note").html($.i18n.prop("disable"));
    }
}

function switchClick(id) {
    var o = $("#" + id);
    if (getSwitch(id)) {
        setSwitch(id, false);
        return false;
    } else {
        setSwitch(id, true);
        return true;
    }
    // if(o.attr("class")=="bg-switch-enable") {
    //     o.attr("class","bg-switch-disable");
    //     o.next(".switch_note").html("Disable");
    // }
    // else {
    //     o.attr("class","bg-switch-enable");
    //     o.next(".switch_note").html("Enable");
    // }
}

function removeChecked(id) {
    $("#" + id).removeClass("checkbox_selected").find("input:checkbox").removeAttr("checked");
}

function addChecked(id) {
    $("#" + id).addClass("checkbox_selected").find("input:checkbox").attr("checked", "checked");
}

function getCheckbox(id) {
    if ($("#" + id).find("input:checkbox").attr("checked")) {
        return true;
    } else {
        return false;
    }
}

function setCheckbox(id, val) {
    if (val) {
        if (getCheckbox(id)) return;
        addChecked(id);
    } else {
        removeChecked(id);
    }
}

function checkboxHandle(id) {
    if ($("#" + id).find("input:checkbox").attr("checked")) {
        removeChecked(id);
        return false;
    } else {
        addChecked(id);
        return true;
    }
}

/**
 * 启用checkbox
 * @method enableCheckbox
 * @param checkbox
 */
function enableCheckbox(checkbox) {
    checkbox.removeClass('disable').removeClass("checked_disable");
}
/**
 * 禁用checkbox
 * @method disableCheckbox
 * @param checkbox
 */
function disableCheckbox(checkbox) {
    var chk = checkbox.find("input:checkbox");
    if (chk.attr("checked")) {
        checkbox.addClass('checked_disable');
    } else {
        checkbox.addClass('disable');
    }
}

/**
 * 提示成功信息
 * @method successOverlay
 * @param {String} msg
 */
// function successOverlay(msg) {
//     if (!msg) msg = 'setting_apply_sucess'
//     hideLoading();
//     showInfo(msg);
// }
function successOverlay(e, t) {
    showOverLay(e || "success_info", "overlay-success", !t)
}

/**
 * 提示失败信息
 * @method successOverlay
 * @param {String} msg
 */
// function errorOverlay(msg) {
//     if (!msg) msg = 'setting_apply_faile'
//     hideLoading();
//     showInfo(msg);
// }
function errorOverlay(e, t) {
    showOverLay(e || "error_info", "overlay-error", !t)
}

function showOverLay(e, t, n) {
    n && hideLoading(), $("#msgDiv").html($.i18n.prop(e)).removeClass().addClass(t), window.scroll(0, 0), $("#msgOverlay").slideDown(), setTimeout(function() { $("#msgOverlay").slideUp() }, 2e3)
}

/**
 * 翻译下拉列表中的选项
 * @method transOption
 * @param {String} transid 下拉列表中需要翻译的id
 * @param {String} isChannel 判断需要翻译的元素是否是channel
 * @return {Function}
 */
function transOption(transid, isChannel) {
    if (isChannel) {
        return function(item) {
            if (item.value != 0) {
                var val = item.value.split("_");
                return val[1] + $.i18n.prop('MHZ') + " " + $.i18n.prop(transid + '_' + val[0]);
            } else {
                return $.i18n.prop(transid + '_0');
            }
        };
    }
    return function(item) {
        return $.i18n.prop(transid + '_' + item.value);
    };
}

/*
	去除字符串左右两边的空格
*/
function trim(stringToTrim) {
    return stringToTrim.replace(/^\s+|\s+$/g, "");
}

function convertSignal(data) {
    var type_2g = ["GSM", "GPRS", "EDGE", "G", "E"];
    var type_3g = ["UJAZZ", "HSDPA", "HSUPA", "HSPA", "HSPA+", "DC-HSPA+", "WCDMA", "TD-SCDMA", "TD", "3G", "TD_SCDMA"];
    var type_4g = ["LTE", "4G", "FDD", "TDD", "TDD-LTE", "FDD-LTE", "TDD_LTE", "FDD_LTE"];
    var network_type = data.sub_network_type ? data.sub_network_type : (data.network_type ? data.network_type : '');
    if ($.inArray(network_type, type_2g) != -1) {
        return data.rssi;
    } else if ($.inArray(network_type, type_3g) != -1) {
        return data.rscp;
    } else if ($.inArray(network_type, type_4g) != -1) {
        return data.lte_rsrp;
    }
}

/**
 * 切换语言时,清除之前页面上的检核信息
 * @method clearValidateMsg
 */
function clearValidateMsg(areaId) {
    areaId = areaId || '*';
    $(areaId + ' label.error').remove();
}

function clearAllErrorLabel() {
    $('.error_message').remove();
}

function showErrorUnderTextbox(idOfTextbox, errormsg, label_id) {
    var errorLabel = '';
    if (label_id != null && label_id != '' && label_id != ' ') {
        errorLabel = "<div class='error_message'><label class='error' id='" + label_id + "'>" + errormsg + '</label><div>';
    } else {
        errorLabel = "<div class='error_message'><label class='error'>" + errormsg + '</label><div>';
    }
    if (0 == $('#' + idOfTextbox).parent().parent().children('.error_message').length) {
        $('#' + idOfTextbox).parent().after(errorLabel);
    }
}

var MACRO_SUPPORT_CHAR_MIN = 32;
var MACRO_SUPPORT_CHAR_MAX = 127;
var MACRO_NOT_SUPPORT_CHAR_COMMA = 44; //,
var MACRO_NOT_SUPPORT_CHAR_QUOTATION_MARK = 34; //"
var MACRO_NOT_SUPPORT_CHAR_COLON = 58; //:
var MACRO_NOT_SUPPORT_CHAR_SEMICOLON = 59; //;
var MACRO_NOT_SUPPORT_BACKSLASH_MARK = 92; //\
var MACRO_NOT_SUPPORT_CHAR_38 = 38; //&
var MACRO_NOT_SUPPORT_CHAR_37 = 37; //%
var MACRO_NOT_SUPPORT_CHAR_43 = 43; //+
var MACRO_NOT_SUPPORT_CHAR_39 = 39; //'
var MACRO_NOT_SUPPORT_CHAR_60 = 60; //<
var MACRO_NOT_SUPPORT_CHAR_62 = 62; //>
var MACRO_NOT_SUPPORT_CHAR_63 = 63; //?

function checkInputChar(str) {
    var i;
    var char_i;
    var num_char_i;

    if (str == "") {
        return true;
    }

    for (i = 0; i < str.length; i++) {
        char_i = str.charAt(i);
        num_char_i = char_i.charCodeAt();
        if ((num_char_i > MACRO_SUPPORT_CHAR_MAX) || (num_char_i < MACRO_SUPPORT_CHAR_MIN)) {
            return false;
        } else if ((MACRO_NOT_SUPPORT_CHAR_COMMA == num_char_i) ||
            (MACRO_NOT_SUPPORT_CHAR_QUOTATION_MARK == num_char_i) ||
            (MACRO_NOT_SUPPORT_CHAR_COLON == num_char_i) ||
            (MACRO_NOT_SUPPORT_CHAR_SEMICOLON == num_char_i) ||
            (MACRO_NOT_SUPPORT_BACKSLASH_MARK == num_char_i) ||
            (MACRO_NOT_SUPPORT_CHAR_38 == num_char_i) ||
            (MACRO_NOT_SUPPORT_CHAR_37 == num_char_i) ||
            (MACRO_NOT_SUPPORT_CHAR_43 == num_char_i) ||
            (MACRO_NOT_SUPPORT_CHAR_39 == num_char_i) ||
            (MACRO_NOT_SUPPORT_CHAR_60 == num_char_i) ||
            (MACRO_NOT_SUPPORT_CHAR_62 == num_char_i) ||
            (MACRO_NOT_SUPPORT_CHAR_63 == num_char_i)) {
            return false;
        } else {
            continue;
        }
    }
    return true;
}

function hasSpaceOrTabAtHead(str) {
    if (0 == str.indexOf(" ") || 0 == str.indexOf("\t")) {
        return true;
    } else {
        return false;
    }
}

var hexcase = 0;
var b64pad = "";
var chrsz = 8;

function hex_md5(s) { return binl2hex(core_md5(str2binl(s), s.length * chrsz)); }

function b64_md5(s) { return binl2b64(core_md5(str2binl(s), s.length * chrsz)); }

function str_md5(s) { return binl2str(core_md5(str2binl(s), s.length * chrsz)); }

function hex_hmac_md5(key, data) { return binl2hex(core_hmac_md5(key, data)); }

function b64_hmac_md5(key, data) { return binl2b64(core_hmac_md5(key, data)); }

function str_hmac_md5(key, data) { return binl2str(core_hmac_md5(key, data)); }

function md5_vm_test() {
    return hex_md5("abc") == "900150983cd24fb0d6963f7d28e17f72";
}

function core_md5(x, len) {
    x[len >> 5] |= 0x80 << ((len) % 32);
    x[(((len + 64) >>> 9) << 4) + 14] = len;

    var a = 1732584193;
    var b = -271733879;
    var c = -1732584194;
    var d = 271733878;

    for (var i = 0; i < x.length; i += 16) {
        var olda = a;
        var oldb = b;
        var oldc = c;
        var oldd = d;

        a = md5_ff(a, b, c, d, x[i + 0], 7, -680876936);
        d = md5_ff(d, a, b, c, x[i + 1], 12, -389564586);
        c = md5_ff(c, d, a, b, x[i + 2], 17, 606105819);
        b = md5_ff(b, c, d, a, x[i + 3], 22, -1044525330);
        a = md5_ff(a, b, c, d, x[i + 4], 7, -176418897);
        d = md5_ff(d, a, b, c, x[i + 5], 12, 1200080426);
        c = md5_ff(c, d, a, b, x[i + 6], 17, -1473231341);
        b = md5_ff(b, c, d, a, x[i + 7], 22, -45705983);
        a = md5_ff(a, b, c, d, x[i + 8], 7, 1770035416);
        d = md5_ff(d, a, b, c, x[i + 9], 12, -1958414417);
        c = md5_ff(c, d, a, b, x[i + 10], 17, -42063);
        b = md5_ff(b, c, d, a, x[i + 11], 22, -1990404162);
        a = md5_ff(a, b, c, d, x[i + 12], 7, 1804603682);
        d = md5_ff(d, a, b, c, x[i + 13], 12, -40341101);
        c = md5_ff(c, d, a, b, x[i + 14], 17, -1502002290);
        b = md5_ff(b, c, d, a, x[i + 15], 22, 1236535329);

        a = md5_gg(a, b, c, d, x[i + 1], 5, -165796510);
        d = md5_gg(d, a, b, c, x[i + 6], 9, -1069501632);
        c = md5_gg(c, d, a, b, x[i + 11], 14, 643717713);
        b = md5_gg(b, c, d, a, x[i + 0], 20, -373897302);
        a = md5_gg(a, b, c, d, x[i + 5], 5, -701558691);
        d = md5_gg(d, a, b, c, x[i + 10], 9, 38016083);
        c = md5_gg(c, d, a, b, x[i + 15], 14, -660478335);
        b = md5_gg(b, c, d, a, x[i + 4], 20, -405537848);
        a = md5_gg(a, b, c, d, x[i + 9], 5, 568446438);
        d = md5_gg(d, a, b, c, x[i + 14], 9, -1019803690);
        c = md5_gg(c, d, a, b, x[i + 3], 14, -187363961);
        b = md5_gg(b, c, d, a, x[i + 8], 20, 1163531501);
        a = md5_gg(a, b, c, d, x[i + 13], 5, -1444681467);
        d = md5_gg(d, a, b, c, x[i + 2], 9, -51403784);
        c = md5_gg(c, d, a, b, x[i + 7], 14, 1735328473);
        b = md5_gg(b, c, d, a, x[i + 12], 20, -1926607734);

        a = md5_hh(a, b, c, d, x[i + 5], 4, -378558);
        d = md5_hh(d, a, b, c, x[i + 8], 11, -2022574463);
        c = md5_hh(c, d, a, b, x[i + 11], 16, 1839030562);
        b = md5_hh(b, c, d, a, x[i + 14], 23, -35309556);
        a = md5_hh(a, b, c, d, x[i + 1], 4, -1530992060);
        d = md5_hh(d, a, b, c, x[i + 4], 11, 1272893353);
        c = md5_hh(c, d, a, b, x[i + 7], 16, -155497632);
        b = md5_hh(b, c, d, a, x[i + 10], 23, -1094730640);
        a = md5_hh(a, b, c, d, x[i + 13], 4, 681279174);
        d = md5_hh(d, a, b, c, x[i + 0], 11, -358537222);
        c = md5_hh(c, d, a, b, x[i + 3], 16, -722521979);
        b = md5_hh(b, c, d, a, x[i + 6], 23, 76029189);
        a = md5_hh(a, b, c, d, x[i + 9], 4, -640364487);
        d = md5_hh(d, a, b, c, x[i + 12], 11, -421815835);
        c = md5_hh(c, d, a, b, x[i + 15], 16, 530742520);
        b = md5_hh(b, c, d, a, x[i + 2], 23, -995338651);

        a = md5_ii(a, b, c, d, x[i + 0], 6, -198630844);
        d = md5_ii(d, a, b, c, x[i + 7], 10, 1126891415);
        c = md5_ii(c, d, a, b, x[i + 14], 15, -1416354905);
        b = md5_ii(b, c, d, a, x[i + 5], 21, -57434055);
        a = md5_ii(a, b, c, d, x[i + 12], 6, 1700485571);
        d = md5_ii(d, a, b, c, x[i + 3], 10, -1894986606);
        c = md5_ii(c, d, a, b, x[i + 10], 15, -1051523);
        b = md5_ii(b, c, d, a, x[i + 1], 21, -2054922799);
        a = md5_ii(a, b, c, d, x[i + 8], 6, 1873313359);
        d = md5_ii(d, a, b, c, x[i + 15], 10, -30611744);
        c = md5_ii(c, d, a, b, x[i + 6], 15, -1560198380);
        b = md5_ii(b, c, d, a, x[i + 13], 21, 1309151649);
        a = md5_ii(a, b, c, d, x[i + 4], 6, -145523070);
        d = md5_ii(d, a, b, c, x[i + 11], 10, -1120210379);
        c = md5_ii(c, d, a, b, x[i + 2], 15, 718787259);
        b = md5_ii(b, c, d, a, x[i + 9], 21, -343485551);

        a = safe_add(a, olda);
        b = safe_add(b, oldb);
        c = safe_add(c, oldc);
        d = safe_add(d, oldd);
    }
    return Array(a, b, c, d);
}

function md5_cmn(q, a, b, x, s, t) {
    return safe_add(bit_rol(safe_add(safe_add(a, q), safe_add(x, t)), s), b);
}

function md5_ff(a, b, c, d, x, s, t) {
    return md5_cmn((b & c) | ((~b) & d), a, b, x, s, t);
}

function md5_gg(a, b, c, d, x, s, t) {
    return md5_cmn((b & d) | (c & (~d)), a, b, x, s, t);
}

function md5_hh(a, b, c, d, x, s, t) {
    return md5_cmn(b ^ c ^ d, a, b, x, s, t);
}

function md5_ii(a, b, c, d, x, s, t) {
    return md5_cmn(c ^ (b | (~d)), a, b, x, s, t);
}

function core_hmac_md5(key, data) {
    var bkey = str2binl(key);
    if (bkey.length > 16) bkey = core_md5(bkey, key.length * chrsz);

    var ipad = Array(16),
        opad = Array(16);
    for (var i = 0; i < 16; i++) {
        ipad[i] = bkey[i] ^ 0x36363636;
        opad[i] = bkey[i] ^ 0x5C5C5C5C;
    }

    var hash = core_md5(ipad.concat(str2binl(data)), 512 + data.length * chrsz);
    return core_md5(opad.concat(hash), 512 + 128);
}

function safe_add(x, y) {
    var lsw = (x & 0xFFFF) + (y & 0xFFFF);
    var msw = (x >> 16) + (y >> 16) + (lsw >> 16);
    return (msw << 16) | (lsw & 0xFFFF);
}

function bit_rol(num, cnt) {
    return (num << cnt) | (num >>> (32 - cnt));
}

function str2binl(str) {
    var bin = Array();
    var mask = (1 << chrsz) - 1;
    for (var i = 0; i < str.length * chrsz; i += chrsz)
        bin[i >> 5] |= (str.charCodeAt(i / chrsz) & mask) << (i % 32);
    return bin;
}

function binl2str(bin) {
    var str = "";
    var mask = (1 << chrsz) - 1;
    for (var i = 0; i < bin.length * 32; i += chrsz)
        str += String.fromCharCode((bin[i >> 5] >>> (i % 32)) & mask);
    return str;
}

function binl2hex(binarray) {
    var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef";
    var str = "";
    for (var i = 0; i < binarray.length * 4; i++) {
        str += hex_tab.charAt((binarray[i >> 2] >> ((i % 4) * 8 + 4)) & 0xF) +
            hex_tab.charAt((binarray[i >> 2] >> ((i % 4) * 8)) & 0xF);
    }
    return str;
}

/*
 * Convert an array of little-endian words to a base-64 string
 */
function binl2b64(binarray) {
    var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
    var str = "";
    for (var i = 0; i < binarray.length * 4; i += 3) {
        var triplet = (((binarray[i >> 2] >> 8 * (i % 4)) & 0xFF) << 16) |
            (((binarray[i + 1 >> 2] >> 8 * ((i + 1) % 4)) & 0xFF) << 8) |
            ((binarray[i + 2 >> 2] >> 8 * ((i + 2) % 4)) & 0xFF);
        for (var j = 0; j < 4; j++) {
            if (i * 8 + j * 6 > binarray.length * 32) str += b64pad;
            else str += tab.charAt((triplet >> 6 * (3 - j)) & 0x3F);
        }
    }
    return str;
}

/**
 * 禁用按钮
 * @method disableBtn
 */
function disableBtn(ele) {
    ele.attr("disabled", "disabled").removeClass("focusIn").addClass("disabled");
}

/**
 * 按钮可用
 * @method enableBtn
 */
function enableBtn(ele) {
    ele.removeAttr("disabled").removeClass("disabled");
}

function isValidIpAddress(address) {
    var addrParts = address.split('.');
    if (addrParts.length != 4) {
        return false;
    }

    for (i = 0; i < 4; i++) {
        if (isNaN(addrParts[i]) == true) //isNaN  if not a number return true,else return false
        {
            return false;
        }

        if (addrParts[i] == '') {
            return false;
        }

        if (addrParts[i].indexOf(' ') != -1) //
        {
            return false;
        }

        if ((addrParts[i].indexOf('0') == 0) && (addrParts[i].length != 1)) {
            return false;
        }
    }

    if ((addrParts[0] <= 0 || addrParts[0] == 127 || addrParts[0] > 223) ||
        (addrParts[1] < 0 || addrParts[1] > 255) ||
        (addrParts[2] < 0 || addrParts[2] > 255) ||
        (addrParts[3] <= 0 || addrParts[3] >= 255)) {
        return false;
    }

    return true;
}

function inetAton(a) {
    var n;

    n = a.split(/\./);
    if (n.length != 4) {
        return 0;
    }
    return ((n[0] << 24) | (n[1] << 16) | (n[2] << 8) | n[3]);
}

function isBroadcastOrNetworkAddress(ipAddress, netmask) {
    var ip;
    var mask;
    var netaddr;
    var broadaddr;

    ip = inetAton(ipAddress);
    mask = inetAton(netmask);
    netaddr = ip & mask;
    broadaddr = netaddr | ~mask;

    if (netaddr == ip || ip == broadaddr) {
        return false;
    }
    return true;
}

function isSameSubnetAddrs(ip1, ip2, mask) {
    var addrParts1 = ip1.split(".");
    var addrParts2 = ip2.split(".");
    var maskParts = mask.split(".");
    for (i = 0; i < 4; i++) {
        if (((Number(addrParts1[i])) & (Number(maskParts[i]))) != ((Number(addrParts2[i])) & (Number(maskParts[i])))) {
            return false;
        }
    }
    return true;
}

function compareStartIpAndEndIp(startIp, endIp) {
    var ipStart = startIp.split(".");
    var ipEnd = endIp.split(".");

    for (i = 0; i < 4; i++) {
        if (parseInt(ipEnd[i], 10) > parseInt(ipStart[i], 10)) {
            break;
        } else if ((parseInt(ipEnd[i], 10) == parseInt(ipStart[i], 10)) && 3 != i) {
            continue;
        } else {
            return false;
        }
    }

    return true;
}

function isBetweenStartIPAndEndIP(ipAddress, startIP, endIP) {
    var num = 0;
    var numStart = 0;
    var numEnd = 0;
    var maskParts = ipAddress.split('.');
    var maskStartIPParts = startIP.split('.');
    var maskEndIPParts = endIP.split('.');

    num = Number(maskParts[0]) * 256 * 256 * 256 + Number(maskParts[1]) * 256 * 256 + Number(maskParts[2]) * 256 + Number(maskParts[3]);
    numStart = Number(maskStartIPParts[0]) * 256 * 256 * 256 + Number(maskStartIPParts[1]) * 256 * 256 + Number(maskStartIPParts[2]) * 256 + Number(maskStartIPParts[3]);
    numEnd = Number(maskEndIPParts[0]) * 256 * 256 * 256 + Number(maskEndIPParts[1]) * 256 * 256 + Number(maskEndIPParts[2]) * 256 + Number(maskEndIPParts[3]);

    if ((num >= numStart) && (num <= numEnd)) {
        return true;
    } else {
        return false;
    }
}

function isValidSubnetMask(mask) {
    var i = 0;
    var num = 0;
    var zeroBitPos = 0,
        oneBitPos = 0;
    var zeroBitExisted = false;

    if ('0.0.0.0' == mask) {
        return false;
    }

    if ('255.255.255.255' == mask) {
        return false;
    }

    var maskParts = mask.split('.');
    if (maskParts.length != 4) {
        return false;
    }

    for (i = 0; i < 4; i++) {
        if (true == isNaN(maskParts[i])) {
            return false;
        }
        if ('' == maskParts[i]) {
            return false;
        }
        if (maskParts[i].indexOf(' ') != -1) {
            return false;
        }

        if ((0 == maskParts[i].indexOf('0')) && (maskParts[i].length != 1)) {
            return false;
        }

        num = parseInt(maskParts[i], 10);
        if (num < 0 || num > 255) {
            return false;
        }
        if (true == zeroBitExisted && 0 != num) {
            return false;
        }
        zeroBitPos = getLeftMostZeroBitPos(num);
        oneBitPos = getRightMostOneBitPos(num);
        if (zeroBitPos < oneBitPos) {
            return false;
        }
        if (zeroBitPos < 8) {
            zeroBitExisted = true;
        }
    }

    return true;
}


function getLeftMostZeroBitPos(num) {
    var i = 0;
    var numArr = [128, 64, 32, 16, 8, 4, 2, 1];

    for (i = 0; i < numArr.length; i++) {
        if ((num & numArr[i]) == 0) {
            return i;
        }
    }

    return numArr.length;
}

function getRightMostOneBitPos(num) {
    var i = 0;
    var numArr = [1, 2, 4, 8, 16, 32, 64, 128];

    for (i = 0; i < numArr.length; i++) {
        if (((num & numArr[i]) >> i) == 1) {
            return (numArr.length - i - 1);
        }
    }

    return -1;
}

function verifyPIN(pin) {
    // var pukpatrn = /^[0-9]{8}$/;
    var pinpatrn = /^[0-9]{4,8}$/;
    if (!pinpatrn.exec(pin)) {
        return false;
    }
    return true;
}

function verifyPUK(puk) {
    var pukpatrn = /^[0-9]{8}$/;
    if (!pukpatrn.exec(puk)) {
        return false;
    }
    return true;
}

function isWifiConnected(user_ip_addr, station_list) {
    return !!_.find(station_list, function(station) {
        return station.ip_addr == user_ip_addr;
    });
}
/**
 * 检查是否有线模式
 * "PPPOE" || "AUTO_PPPOE"
 * @method checkCableMode
 */
function checkCableMode(currentMode) {
    return currentMode == "PPPOE" || currentMode == "AUTO_PPPOE";
}

function syncSelectAndChosen(select, choices) {
    var choicesNums = getSelectValFromChosen(choices);
    select.val(choicesNums);
    return choicesNums;
}

function getSelectValFromChosen(choices) {
    var choicesNums = [];
    $.each(choices, function(i, n) {
        var arr = $(n).text().split('/');
        choicesNums.push(arr[arr.length - 1]);
    });
    return choicesNums;
}

function renderCustomElement(container) {
    if (!container) {
        container = $("#container");
    }
    var radios = container.find("input[type='radio']");
    var checkboxes = container.find("input[type='checkbox']");
    $.each(radios, function(i, n) {
        var $el = $(n),
            ch = 'checked',
            checkAction = $el.prop('checked') ? true : false;
        $el.closest('.radio')[checkAction ? 'addClass' : 'removeClass'](ch) && checkAction ? $el.attr(ch, true) : $el.removeAttr(ch);
    });
    $.each(checkboxes, function(i, n) {
        var $el = $(n),
            ch = 'checked',
            checkAction = $el.prop('checked') ? true : false;
        $el.closest('.checkbox')[checkAction ? 'addClass' : 'removeClass'](ch) && checkAction ? $el.attr(ch, true) : $el.removeAttr(ch);
    });
}

/**
 * 检查是否联网
 * "ppp_connected" || "ipv6_connected" || "ipv4_ipv6_connected"
 * @method checkConnectedStatus
 */
function checkConnectedStatus(currentConnStatus) {
    return currentConnStatus == "ppp_connected" || currentConnStatus == "ipv6_connected" || currentConnStatus == "ipv4_ipv6_connected";
}

/**
 * 显示进度条
 * @method showProgressBar
 * @param {String} msg
 * @param {String} content loading 文本
 */
function showProgressBar(msg, content) {
    if (msg) {
        $('#barMsg').html($.i18n.prop(msg));
    }
    $('#progress').modal({
        position: '30%',
        overlayId: 'confirm-overlay',
        containerId: 'confirm-container',
        minHeight: 140,
        persist: true,
        focus: false,
        escClose: false,
        containerCss: { 'background-color': '#fff' }
    });

    if (content) {
        $("#progress #progress_container").html(content);
    } else {
        $("#progress #progress_container").html("");
    }
    $("#confirm-container").css("width", "475px");
}

/**
 * 显示进度条百分比
 * @method setProgressBar
 * @param {int} percents 百分比
 */
function setProgressBar(percents) {
    $("#bar").width(400 * percents / 100);
    $("#barValue").text(percents + "%");
}

/**
 * 隐藏进度条
 * @method hideProgressBar
 */
function hideProgressBar() {
    $.modal.close();
    setProgressBar(0);
    $('#barMsg').html('');
}

function verifyDeviceInfo(field) {
    if (field && field != "" && field != "0.0.0.0") {
        return field;
    } else {
        return "— —";
    }
}

/**
 * 检查是否有线模式
 * "PPPOE" || "AUTO_PPPOE"
 * @method checkCableMode
 */
function checkCableMode(currentMode) {
    return currentMode == "PPPOE" || currentMode == "AUTO_PPPOE";
}

function signalFormat(signal) {
    if (signal) {
        if (signal > 0) {
            return "-" + signal + " dBm";
        } else {
            return signal + " dBm";
        }
    } else {
        return "— —";
    }
}

function isIE() { //ie?
    if (!!window.ActiveXObject || "ActiveXObject" in window) { return true; } else { return false; }
}

function startWith(str, str2) {
    return str.indexOf(str2) == 0
}

function endWith(str, str2) {
    var lastIndex = str.lastIndexOf(str2)
    if (lastIndex >= 0) {
        return str.substring(lastIndex) == str2
    }
    return false
}

function showPromptForCus(e, t, n, o, r, i, a) {
    popupForCus({
        title: $.i18n.prop(i),
        img: "img/confirm.png",
        msg: e,
        minHeight: n,
        showInput: !0,
        defaultValue: o,
        propId: r
    }, a), $("#yesbtnForCus, #nobtnForCus,#yesSpanForCus,#noSpanForCus").unbind("click").show(), $("#okbtnForCus,#okSpanForCus").hide(), "logIn" == i ? ($("#yesbtnForCus").val($.i18n.prop("logIn")), $("#yesbtnForCus2").val($.i18n.prop("logIn")), $("#yesbtnForCus").hide(), $("#yesbtnForCus2").show(), $("#nobtnForCus").val($.i18n.prop("cancel"))) : ($("#yesbtnForCus").show(), $("#yesbtnForCus2").hide()), $("#yesbtnForCus").click(function() {
        $.isFunction(t) && t() && ($("#confirmForCus").hide(), $.modal.close())
    }), $("#nobtnForCus,#closeForCus").click(function() {
        $("#confirmForCus").hide(), $.modal.close()
    }), $("#promptInputForCus2", "#confirmForCus").unbind("keypress").bind("keypress", function(e) {
        13 == e.keyCode && $("#yesbtnForCus").trigger("click")
    })
}

function popupForCus(e, t) {
    $.modal.close();
    var n = ("#frmUSSD" == e.propId || e.minWidth, e.minHeight || 140),
        o = e.propId,
        r = "400px";
    r = $(window).width() <= 479 ? "300px" : 479 < $(window).width() && $(window).width() <= 690 ? "340px" : 690 < $(window).width() && $(window).width() <= 960 ? "380px" : "400px", r = "#frmUSSD" == e.propId ? "620px" : r;
    var i = 0 != t;
    $(o).modal({
        position: ["150%"],
        overlayId: "confirm-overlay",
        containerId: "confirm-container",
        escClose: !1,
        minWidth: r,
        minHeight: n,
        fixed: i
    });
    var a = $("div#confirmForCus");
    "string" == typeof e.msg ? ($("#popTitleForCus,#popTitleForCus2").html($.i18n.prop(e.title)), $(".message", a).html($.i18n.prop(e.msg))) : (params.push(e.msg.params), $(".message", a).html($.i18n.prop.apply(null, _.flatten(params))));
    var c = $("div.promptDiv", a);
    "#new_profile" == e.propId && $("#confirm-container").css("width", "609px"), !0 === e.showInput ? ($("input#promptInputForCus", c).val(e.defaultValue ? e.defaultValue : ""), $(".promptErrorLabel", c).empty()) : c.hide(), $("#closeForCusImgIn").attr("title", $.i18n.prop("windows_close_title"))
}

/**
 * 速度及流量翻译
 * 
 * @method transUnit
 * @param {Number}
 *            data 速度值
 * @param {Boolean}
 *            isSpeed 是否是翻译速度
 */
function transUnit(data, isSpeed) {
    var result = getDisplayVolume1(data, isSpeed);
    if (result == "") {
        result = isSpeed ? "0b" : "0MB";
    }
    if (isSpeed) {
        result += "/s";
    }
    return result;
}

function getDisplayVolume1(volume, isSpeed) {
    volume = parseInt(volume, 10);
    if (volume == "" || volume == "0") {
        return "";
    }
    var needReverse = false;
    if (volume < 0) {
        needReverse = true;
        volume = 0 - volume;
    }
    var numberOfBytesInOneB = 1;
    var numberOfBytesInOneKB = numberOfBytesInOneB * 1024;
    var numberOfBytesInOneMB = numberOfBytesInOneKB * 1024;
    var numberOfBytesInOneGB = numberOfBytesInOneMB * 1024;
    var numberOfBytesInOneTB = numberOfBytesInOneGB * 1024;

    var labelForOneB = isSpeed ? 'b' : 'B';
    var labelForOneKB = isSpeed ? 'Kb' : 'KB';
    var labelForOneMB = isSpeed ? 'Mb' : 'MB';
    var labelForOneGB = isSpeed ? 'Gb' : 'GB';
    var labelForOneTB = isSpeed ? 'Tb' : 'TB';

    if (isSpeed) {
        volume = volume * 8;
    }
    var vol = volume / numberOfBytesInOneTB;
    var displayString = roundToTwoDecimalNumber(vol) + labelForOneTB;
    if (vol < 0.5) {
        vol = volume / numberOfBytesInOneGB;
        displayString = roundToTwoDecimalNumber(vol) + labelForOneGB;

        if (vol < 0.5) {
            vol = volume / numberOfBytesInOneMB;
            displayString = roundToTwoDecimalNumber(vol) + labelForOneMB;
            if (isSpeed) {
                if (vol < 0.5) {
                    vol = volume / numberOfBytesInOneKB;
                    displayString = roundToTwoDecimalNumber(vol) + labelForOneKB;

                    if (vol < 0.5) {
                        vol = volume;
                        displayString = roundToTwoDecimalNumber(vol) + labelForOneB;
                    }
                }
            }
        }
    }
    if (needReverse) {
        displayString = "-" + displayString;
    }
    return displayString;
}

function transTimeUnit(data) {
    data = parseFloat(data);
    if (data == "") {
        return result = "0hour";
    }
    var needReverse = false;
    if (data < 0) {
        needReverse = true;
        data = 0 - data;
    }

    var labelForOneMinute = 'minute';
    var labelForOneHour = 'hour';

    var vol = data / 3600;
    var result = roundToTwoDecimalNumber(vol) + labelForOneHour;
    if (vol < 1) {
        vol = data / 60;
        result = roundToTwoDecimalNumber(vol) + labelForOneMinute;
    }
    if (needReverse) {
        result = "-" + result;
    }
    return result;
}

// checkbox start
$(document).ready(function() {
    // checkbox 绑定有click事件，需要手动处理时，需要增加 manualControl=“true"
    $("[manualControl!=true].checkbox").live("click", function(event) {
        var $this = $(this);
        if ($this.hasClass('disable')) {
            return false;
        }
        var checkbox = $this.find("input:checkbox");
        if (checkbox.attr("checked")) {
            checkbox.removeAttr("checked");
        } else {
            checkbox.attr("checked", "checked");
        }
        checkCheckbox(checkbox);
        event.stopPropagation();
        return true;
    });

    $('input[type="text"][noAction!="true"],input[type="password"][noAction!="true"],select').live("focusin", function(event) {
        $(this).addClass("focusIn");
    }).live("focusout", function(event) {
        $(this).removeClass("focusIn");
    });

    $(".form-note .notes-title").live('click', function() {
        var $this = $(this);
        $this.siblings("ul.notes-content:first").slideToggle();
        $this.toggleClass("notes-dot");
    });
});